package cn.school.publicPhone.service.impl;

import cn.school.common.utils.JwtTokenUtil;
import cn.school.common.utils.RedisUtils;
import cn.school.common.utils.StudentInfoDetails;
import cn.school.common.utils.SysUserUtils;
import cn.school.publicPhone.dao.StudentContactsDao;
import cn.school.publicPhone.service.PhoneLoginService;
import cn.school.publicPhone.service.StudentCallService;
import cn.school.publicPhone.util.BaiduAIUtils;
import cn.school.student.dao.StudentInfoDao;
import cn.school.student.entity.StudentContacts;
import cn.school.student.entity.StudentInfo;
import cn.school.student.service.StudentInfoService;
import cn.school.sys.dao.SysUserDao;
import cn.school.sys.entity.SysUser;
import cn.school.sys.service.OnlineUserService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.school.common.datasource.DynamicDataSourceContextHolder.log;

@Service
@Slf4j
public class PhoneLoginServiceImpl implements PhoneLoginService {
    @Autowired
    private RedisUtils redisUtils;
    @Resource
    private StudentInfoDao studentInfoDao;
    @Resource
    private UserDetailsService userDetailsService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Resource
    private OnlineUserService onlineUserService;
    @Resource
    private StudentInfoService studentInfoService;
    
    @Resource
    private StudentContactsDao studentContactsDao;
    
    @Resource
    private StudentCallService studentCallService;

    @Override
    public Map<String, Object> autoFaceLogin(String imageBase64, HttpServletRequest request) {
        String baiduToken = redisUtils.get("baidu_face_token");
        if(StringUtils.isEmpty(baiduToken)){
            baiduToken = BaiduAIUtils.getAuth();
            redisUtils.set("baidu_face_token",baiduToken,2592000);
        }
        String resultStr = BaiduAIUtils.getFaceDiffInfo(baiduToken,imageBase64);
        log.info(resultStr);
        JSONObject json = JSON.parseObject(resultStr);
        boolean isSuccess = false;
        String baiduUserId = null;
        Map<String,Object> resultMap = new HashMap<>();
        if("0".equals(String.valueOf(json.get("error_code")))) {//识别成功
            String result = JSON.toJSONString(json.get("result"));
            String userListStr = JSON.toJSONString(JSON.parseObject(result).get("user_list"));
            List<Map<String,Object>> userList = JSON.parseObject(userListStr,List.class);
            for(Map<String,Object> map:userList) {
                baiduUserId = (String) map.get("user_id");
                BigDecimal score = new BigDecimal(String.valueOf(map.get("score")));
                BigDecimal threshold = new BigDecimal("85");
                if(score.compareTo(threshold)>=0){
                    //识别成功
                    isSuccess = true;
                    break;
                }
            }
            LambdaQueryWrapper<StudentInfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StudentInfo::getId,Long.valueOf(baiduUserId));
            StudentInfo user = studentInfoDao.selectOne(wrapper);

            String token = this.login(user,request);
            //查询用户联系人，学生基本信息，通话余额
            LambdaQueryWrapper<StudentContacts> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(StudentContacts::getStudentId, user.getStudentId());
            List<StudentContacts> studentContacts = studentContactsDao.selectList(queryWrapper);
            
            // 获取剩余通话时长
            String remainingDuration = studentCallService.getStudentRemainingDuration(user.getStudentId());
    
            resultMap.put("token",token);
            resultMap.put("code",200);
            resultMap.put("userInfo", user);
            resultMap.put("contacts", studentContacts);
            resultMap.put("callDuration", remainingDuration);
            log.info(result);
        }else{
            resultMap.put("msg","人脸未注册");
            resultMap.put("code",500);
        }
        return resultMap;
    }

    @Override
    public String faceRegisterToBaidu(Map<String,String> paramMap) {
        String baiduToken = redisUtils.get("baidu_face_token");
        if(StringUtils.isEmpty(baiduToken)){
            baiduToken = BaiduAIUtils.getAuth();
            redisUtils.set("baidu_face_token",baiduToken,2592000);
        }
        try {
            String result = BaiduAIUtils.registerToBaidu(paramMap,baiduToken);
            log.info(result);
            JSONObject json = JSON.parseObject(result);
            if("0".equals(String.valueOf(json.get("error_code")))) {//识别成功
                return "";
            }else{
                return json.get("error_msg").toString();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    public String login(StudentInfo user, HttpServletRequest request) {
        String token = null;
        //密码需要客户端加密后传递
        try {

            StudentInfoDetails userDetails = new StudentInfoDetails(user);
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails.getUsername());
            StudentInfo studentInfoLogin = SysUserUtils.getStudentUser();
            // 保存在线信息
            onlineUserService.saveAppStudent(studentInfoLogin, token, jwtTokenUtil.getExpiration(), request);

            boolean singleLogin = false;

            if (singleLogin) {
                //踢掉之前已经登录的token
                onlineUserService.checkAppStudentLoginOnUser(studentInfoLogin.getPhone(), token);
            }
        } catch (AuthenticationException e) {
            log.warn("登录异常:{}", e.getMessage());
        }
        return token;
    }

    @Override
    public String updateFaceRegisterToBaidu(Map<String, String> paramMap) {
        String baiduToken = redisUtils.get("baidu_face_token");
        if(StringUtils.isEmpty(baiduToken)){
            baiduToken = BaiduAIUtils.getAuth();
            redisUtils.set("baidu_face_token",baiduToken,2592000);
        }
        try {
            String result = BaiduAIUtils.updateFaceToBaidu(paramMap,baiduToken);
            log.info(result);
            JSONObject json = JSON.parseObject(result);
            if("0".equals(String.valueOf(json.get("error_code")))) {//识别成功
                return "";
            }else{
                return json.get("error_msg").toString();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public String deleteFaceRegisterToBaidu(Map<String, String> paramMap) {
        String baiduToken = redisUtils.get("baidu_face_token");
        if(StringUtils.isEmpty(baiduToken)){
            baiduToken = BaiduAIUtils.getAuth();
            redisUtils.set("baidu_face_token",baiduToken,2592000);
        }
        try {
            String result = BaiduAIUtils.deleteFaceToBaidu(paramMap,baiduToken);
            log.info(result);
            JSONObject json = JSON.parseObject(result);
            if("0".equals(String.valueOf(json.get("error_code")))) {//识别成功
                return "";
            }else{
                return json.get("error_msg").toString();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }
}
